package com.weiqiao.api.service.impl;

import com.google.gson.Gson;
import com.mingsoft.util.JsonUtil;
import com.mingsoft.util.StringUtil;
import com.mongodb.client.model.Filters;
import com.weiqiao.api.domain.*;
import com.weiqiao.api.domain.dto.TeamApiEntityDTO;
import com.weiqiao.api.domain.vo.OrderApiVO;
import com.weiqiao.api.domain.vo.OrderListApiVo;
import com.weiqiao.api.repository.*;
import com.weiqiao.api.service.IOrderApiService;
import com.weiqiao.api.until.ApiResUtil;
import com.weiqiao.api.until.SnowFlake;
import com.weiqiao.mall.domain.TeamEntity;
import com.weiqiao.modules.monitor.service.RedisService;
import com.weiqiao.utils.DateUtil;
import com.weiqiao.utils.HttpRequest;
import com.weiqiao.utils.Tool;
import org.apache.commons.collections.CollectionUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author ChenYF
 * @Description
 * @Date 2020/7/28 15:46
 */
@Service("OrderApiService")
public class OrderApiService implements IOrderApiService {

    // 雪花算法工具类
    private static final SnowFlake SNOW_FLAKE = new SnowFlake(2, 3);

    @Autowired
    private ICardCommodityApiRepository cardCommodityApiRepository;

    @Autowired
    private IAppuserApiRepository appuserApiRepository;

    @Autowired
    private ITeamApiRepository teamApiRepository;

    @Autowired
    private IOrderApiRepository orderApiRepository;

    @Autowired
    private ICommodityApiRepository commodityApiRepository;

    @Autowired
    private IAccountDetailApiRepository accountDetailApiRepository;

    /**
     * redis存储轮询策略
     */
    @Autowired
    private RedisService redisService;

    @Override
    public ApiResponseEntity addCardOrder(OrderApiVO vo) {
        Integer company_id = vo.getCompany_id();
        // 参数校验
        if (StringUtil.isBlank(vo.getUser_name())) {
            return ApiResUtil.buildRes(false, "请输入用户名称！");
        }
        OrderApiEntity order = setOrderEntity(vo);
        order.setState(0);
        // 查询商品信息
        String card_s = cardCommodityApiRepository.findCommodityDetail(
                company_id,
                new Document()
                        .append("commodity_id", vo.getCommodity_id())
                        .append("state", 0)
        );
        if (StringUtil.isBlank(card_s)) {
            return ApiResUtil.buildRes(false, "商品不存在！");
        }
        // 设置商品信息
        CardCommodityApiEntity cardEntity = new Gson().fromJson(card_s, CardCommodityApiEntity.class);
        // 判断商品是否需要收集身份证信息
        boolean bool = cardEntity.getIs_add_id_card() == 1;
        if (bool) {
            String idCade = vo.getId_code();
            if (StringUtil.isBlank(idCade)) {
                return ApiResUtil.buildRes(false, "请填写身份证号码！");
            }
            String check_id_cade = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
            if (!idCade.matches(check_id_cade)) {
                return ApiResUtil.buildRes(false, "请输入正确的身份证号码！");
            }
        }
        OrderApiEntity.order_item item = new OrderApiEntity.order_item();
        item.setCommodity_id(cardEntity.getCommodity_id());
        item.setCommodity_name(cardEntity.getName());
        item.setPro_title(cardEntity.getPro_title());
        item.setCover_url(cardEntity.getCover_url());
        item.setVariety_id(cardEntity.getVariety_id());
        item.setCardCode(cardEntity.getRelation_credit_card_id());
        item.setSecond_variety_id(cardEntity.getSecond_variety_id());
        order.setOrderItemList(Arrays.asList(item));
        // 设置用户信息
        String user_s = appuserApiRepository.getAppUserByFilter(company_id, new Document("user_id", vo.getUser_id()));
        if (StringUtil.isBlank(user_s)) {
            return ApiResUtil.buildRes(false, "请重新登录！");
        }
        AppUserApiEntity user = new Gson().fromJson(user_s, AppUserApiEntity.class);
        order.setUser_name(vo.getUser_name());
        order.setIcon_url(user.getIcon_url());
        // 用户是否需要修改
        boolean is_update = false;
        Document doc = new Document();
        if (StringUtil.isBlank(user.getPhone())) {
            doc.append("phone", vo.getPhone());
            is_update = true;
            // 根据手机号查询用户 判断当前是否需要合并账号
            String s = appuserApiRepository.getAppUserByFilter(company_id, new Document("phone", vo.getPhone()));
            AppUserApiEntity entity = StringUtil.isBlank(s) ? new AppUserApiEntity() : new Gson().fromJson(s, AppUserApiEntity.class);
            // 判断该账号是否有被合并过
            if (StringUtil.isBlank(entity.getUnionid())) {
                // 合并账号
                doc.append("member_type", entity.getMember_type());
                doc.append("active_team", entity.getActive_team());
                doc.append("user_name", entity.getUser_name());
                // 删除合并前的账号
                appuserApiRepository.delUser(company_id, new Document("user_id", entity.getUser_id()));
            }
        }
        if (StringUtil.isBlank(user.getId_cade())) {
            doc.append("id_code", vo.getId_code());
            is_update = true;
        }
        if (StringUtil.isBlank(user.getUser_name())) {
            doc.append("user_name", vo.getUser_name());
            is_update = true;
        }
        if (is_update) appuserApiRepository.updateAppUser(company_id, Filters.eq("user_id", user.getUser_id()), doc, false);
        if (!StringUtil.isBlank(user.getRecommend_id())) {
            order.setRecommend_id(user.getRecommend_id());
            String recommend_user_s = appuserApiRepository.getAppUserByFilter(company_id, new Document("user_id", user.getRecommend_id()));
            AppUserApiEntity recommendUser = StringUtil.isBlank(recommend_user_s) ? new AppUserApiEntity() : new Gson().fromJson(recommend_user_s, AppUserApiEntity.class);
            order.setRecommend_name(recommendUser.getUser_name());
        }
        if (!StringUtil.isBlank(user.getTeam_id())) {
            order.setTeam_id(user.getTeam_id());
            String team_s = teamApiRepository.teamDtail(company_id, new Document("team_id", user.getTeam_id()));
            TeamApiEntityDTO dto = StringUtil.isBlank(team_s) ? new TeamApiEntityDTO() : new Gson().fromJson(team_s, TeamApiEntityDTO.class);
            order.setTeam_name(dto.getTeam_name());
        }
        boolean is_ok = orderApiRepository.addOrder(company_id, Document.parse(new Gson().toJson(order)));
        // 返回三方跳转链接
        String url = this.getJumpUrl(cardEntity, vo);
        return ApiResUtil.buildRes(is_ok, url);
    }

    @Override
    public ApiResponseEntity addIntegralOrder(OrderApiVO vo) {
        Integer company_id = vo.getCompany_id();
        OrderApiEntity order = setOrderEntity(vo);
        order.setState(50);
        order.setOrder_type(1);
        // 查询用户信息
        String user_s = appuserApiRepository.getAppUserByFilter(company_id, new Document("user_id", vo.getUser_id()));
        if (StringUtil.isBlank(user_s)) {
            return ApiResUtil.buildRes(false, "请重新登录！");
        }
        AppUserApiEntity user = new Gson().fromJson(user_s, AppUserApiEntity.class);
        order.setScore(user.getScore());
        order.setUser_name(user.getUser_name());
        order.setIcon_url(user.getIcon_url());
        // 查询商品信息
        String commodity_s = commodityApiRepository.findCommodityDetail(
                new Document()
                        .append("commodity_id", vo.getCommodity_id())
                        .append("company_id", company_id)
                        .append("state", 0)
                        .append("delete_flag", 0)
        );
        if (StringUtil.isBlank(commodity_s)) {
            return ApiResUtil.buildRes(false, "商品不存在！");
        }
        CommodityApiEntity commodity = new Gson().fromJson(commodity_s, CommodityApiEntity.class);
        // 获取商品价格
        double price = commodity.getScore_type() == 0 ? commodity.getVip_price() : commodity.getSell_score();
        if (vo.getCommodity_price() != price) {
            return ApiResUtil.buildRes(false, "商品价格发生变动，请重新下单！");
        }
        // 判断当前积分是否够用
        if (user.getScore() < price) {
            return ApiResUtil.buildRes(false, "当前余额不足！");
        }

        String url =
                StringUtil.isBlank(commodity.getCover_url()) && commodity.getLink_url().size() > 0
                        ? commodity.getLink_url().get(0).getUrl()
                        : commodity.getCover_url();

        OrderApiEntity.order_item item = new OrderApiEntity.order_item();
        item.setCommodity_id(commodity.getCommodity_id());
        item.setCommodity_name(commodity.getName());
        item.setPro_title(commodity.getPro_title());
        item.setCover_url(url);
        item.setVariety_id(commodity.getVariety_id());
        item.setSecond_variety_id(commodity.getSecond_variety_id());
        item.setAmount(price);
        item.setVip_price(price);
        item.setNum(1);
        item.setAccount_number(vo.getAccount_number());
        order.setOrderItemList(Arrays.asList(item));
        order.setAmount_total(commodity.getVip_price());
        boolean is_ok = orderApiRepository.addOrder(company_id, Document.parse(new Gson().toJson(order)));
        // 扣除用户积分
        appuserApiRepository.updateAppUser(
                company_id,
                new Document("user_id", vo.getUser_id()),
                new Document("score", user.getScore() - price),
                false
        );
        // 生成积分流水
        addAccountDetail(company_id, price, user, commodity);
        return ApiResUtil.buildRes(is_ok, "订单创建" + (is_ok ? "成功" : "失败") + "！");
    }

    @Override
    public String getPhoneCard(int companyId, int user_id, String phone) {
        String code = redisService.getCodeVal("pwd:" + phone);
        if (!StringUtil.isBlank(code)) return code;
        // 生成验证码
        code = Tool.getRandom();
        Map map = new HashMap();
        map.put("account", "907121");
        map.put("pwd", "C43D7D20C3A59E59207D35A7544E5C9F");
        map.put("mobiles", phone);
        map.put("content", "【魂斗啰啰】您的验证码" + code + "，该验证码5分钟内有效，请勿泄露于他人！");
        // 发送验证码
        String url = "http://47.111.3.24:8080/api/v1/send";
        HttpRequest.postForForm(url, map);
        // 存储Redis
        redisService.saveValAndSetExpire("pwd:" + phone, code, 300);
        return code;
    }

    @Override
    public List<OrderApiEntity> getOrderList(OrderListApiVo vo) {
        Integer company_id = vo.getCompany_id();
        // 检索条件拼接
        List<OrderApiEntity> orderList = new ArrayList<>();
        // 排序条件
        Document sort = new Document("create_date", -1);
        // 分页条件
        int skip = vo.getPage_num() * vo.getPage_size();
        Document doc = new Document("order_type", Integer.parseInt(vo.getOrder_type()));
        // 订单状态
        if (StringUtil.isInteger(vo.getStatus())) {
            doc.append("state", vo.getStatus());
        }
        // 是否为团队订单
        if (vo.getIs_team() == 1) {
            // 团队订单
            doc.append("user_id", new Document("$in", userids(company_id, vo.getUser_id())));
        } else {
            // 个人订单
            doc.append("user_id", vo.getUser_id());
        }
        List<String> list = orderApiRepository.getOrderListAndPage(company_id, doc, sort, skip, vo.getPage_size());
        if (list != null && list.size() > 0) {
            list.forEach(order -> {
                OrderApiEntity entity = new Gson().fromJson(order, OrderApiEntity.class);
                orderList.add(entity);
            });
        }
        return orderList;
    }

    /**
     * 获取跳转地址
     *
     * @param cardEntity
     * @param vo
     * @return
     */
    private String getJumpUrl(CardCommodityApiEntity cardEntity, OrderApiVO vo) {
        String url;
        if (CollectionUtils.isEmpty(cardEntity.getRelation_card_list())) {
            // 若商品没有填写跳转链接，则网络请求老系统，获取当前银行，当前卡的跳转链接
            url = getGenerateUrl(cardEntity, vo);
        } else {
            // 若商品填写的有跳转链接，采用轮询的策略，查询以及取出将要跳转的连接
            url = getCardListUrl(cardEntity, vo);
        }
        return url;
    }

    /**
     * 网络请求老系统,获取生成的url
     *
     * @param cardEntity
     * @param vo
     * @return
     */
    private String getGenerateUrl(CardCommodityApiEntity cardEntity, OrderApiVO vo) {
        Map map = new HashMap<>();
        map.put("channelCode", "f873d033229c4199b2bc5c01dbc3fbc6");
        map.put("cardCode", cardEntity.getRelation_credit_card_id());
        map.put("name", vo.getUser_name());
        map.put("phoneNum", vo.getPhone());
        map.put("idCard", StringUtil.isBlank(vo.getId_code()) ? "420" : vo.getId_code());
        String requestUrl = "https://ad.fulu.com/channelApi/getLink";
        String result = HttpRequest.doGet(requestUrl, map);
        Map<String, Object> entityMap = JsonUtil.getMap4Json(result);
        if (StringUtil.isBlank(entityMap.get("data"))) return "";
        Map<String, Object> entity = JsonUtil.getMap4Json(entityMap.get("data").toString());
        if (StringUtil.isBlank(entity.get("url"))) return "";
        return entity.get("url").toString();
    }

    /**
     * 获取商品自身的跳转地址，轮循获取其中一个
     *
     * @param cardEntity
     * @param vo
     * @return
     */
    private String getCardListUrl(CardCommodityApiEntity cardEntity, OrderApiVO vo) {
        String url;
        // 首先从Redis中获取，若没有，则直接取传递下来的信用卡实体，从中取一条，且删除这一条。剩下的存Redis
        // 若有，则Redis所取数据转实体，取一条，且删除。判断集合是否还有没有数据，没有则传递下来的信用卡实体存Redis，否则剩下的存Redis
        String result = redisService.get("bank_card_list_" + cardEntity.getCommodity_id());
        if (StringUtil.isBlank(result)) {
            url = cardEntity.getRelation_card_list().get(0).getRelation_card_url();
            cardEntity.getRelation_card_list().remove(0);
            redisService.set("bank_card_list_" + cardEntity.getCommodity_id(), cardEntity);
        } else {
            CardCommodityApiEntity entity = new Gson().fromJson(result, CardCommodityApiEntity.class);
            url = entity.getRelation_card_list().get(0).getRelation_card_url();
            entity.getRelation_card_list().remove(0);
            if (CollectionUtils.isEmpty(entity.getRelation_card_list())) {
                redisService.set("bank_card_list_" + cardEntity.getCommodity_id(), cardEntity);
            } else {
                redisService.set("bank_card_list_" + cardEntity.getCommodity_id(), entity);
            }
        }

        return url;
    }

    /**
     * 设置订单基本信息
     *
     * @param vo 订单基本信息
     * @return
     */
    private OrderApiEntity setOrderEntity(OrderApiVO vo) {
        OrderApiEntity order = new OrderApiEntity();
        order.setOrder_no(String.valueOf(SNOW_FLAKE.nextId()));
        order.setCreate_date(String.valueOf(System.currentTimeMillis()));
        order.setFormart_create_date(DateUtil.format(new Date(), "yyyy-MM-dd"));
        order.setUser_id(vo.getUser_id());
        order.setUser_name(vo.getUser_name());
        order.setNickname(vo.getNickname());
        order.setPhone(vo.getPhone());
        order.setCompany_id(vo.getCompany_id());
        return order;
    }

    /**
     * 获得下级用户id
     *
     * @param company_id 公司id
     * @param user_id    用户id
     * @return
     */
    private List<Integer> userids(Integer company_id, Integer user_id) {
        List<String> teamIds = new ArrayList<>();
        // 查询用户信息
        String user_s = appuserApiRepository.getAppUserByFilter(company_id, Filters.eq("user_id", user_id));
        AppUserApiEntity user = new Gson().fromJson(user_s, AppUserApiEntity.class);
        //判断用户角色，分别显示内容（只有省长团长才会显示该内容）
        switch (user.getMember_type()) {
            case 3: // 省长
                // 查询团队表，获得该团长创建的团队信息
                List<String> list = teamApiRepository.getTeamList(company_id, new Document("create_id", user_id));
                if (CollectionUtils.isNotEmpty(list)) {
                    list.forEach(s -> teamIds.add(new Gson().fromJson(s, TeamEntity.class).getTeam_id()));
                }
                break;
            case 2: // 团长
                teamIds.add(user.getTeam_id());
                break;
            default:
                break;
        }
        // 查询用户信息
        List<String> list = appuserApiRepository.getUserBySort(
                company_id,
                new Document("$or", Arrays.asList(
                        new Document("team_id", new Document("$in", teamIds)), // 团成员
                        new Document("recommend_id", user_id)) // 邀请人为当前id的客户信息
                ),
                Filters.eq("create_time", -1)
        );
        if (CollectionUtils.isEmpty(list)) {
            return Arrays.asList(user_id);
        }
        // 查询当前用户的下级用户
        List<Integer> resultList = new ArrayList<>();
        list.forEach(s -> resultList.add(new Gson().fromJson(s, AppUserApiEntity.class).getUser_id()));
        // 添加自己的用户信息，查看自己订单
        resultList.add(user_id);
        return resultList;
    }

    /**
     * 积分下单生成流水
     *
     * @param company_id 公司id
     * @param price      订单中心
     * @param user       用户信息
     * @param commodity  商品信息
     * @return
     */
    private boolean addAccountDetail(Integer company_id, double price, AppUserApiEntity user, CommodityApiEntity commodity) {
        AccountDetailApiEntity detailEntity = new AccountDetailApiEntity();
        detailEntity.setAccount_no(String.valueOf(System.currentTimeMillis()));
        // 提现金额
        detailEntity.setAccount_money(price);
        detailEntity.setPhone(user.getPhone());
        // 佣金提现
        detailEntity.setHappen_proceed(3);
        // 支出
        detailEntity.setAccount_state(1);
        detailEntity.setAccount_type(1);
        detailEntity.setUser_id(user.getUser_id());
        detailEntity.setName(user.getNickname());
        detailEntity.setIcon_url(user.getIcon_url());
        detailEntity.setRemark("积分兑换商品(" + commodity.getName() + ")");
        detailEntity.setResult_type(1);
        detailEntity.setDelete_flag(0);
        detailEntity.setCompany_id(company_id);
        detailEntity.setCreat_time(String.valueOf(System.currentTimeMillis()));
        return accountDetailApiRepository.addAccountDetail(company_id, new Gson().toJson(detailEntity));
    }
}
